#include <retro.h>
#include "retro.creator.h"
#include "retro.scriptingapi.h"

using namespace Retro::Creator::Toolbox;
using namespace SPLib::Geom;

#define DEBUGGER_MARGIN    4

enum DebuggerElement
{
  DebuggerScript = 0x0001,
};

VOID  Debugger::Workspace::onMouseDown(Event::MouseEvent& iEvent)
{
  mDebugger.mPlayer.focus();
}

VOID  Debugger::Workspace::onEraseBackground(
  Event::EraseBackgroundEvent& iEvent
  )
{
  *iEvent.handled = TRUE;
}

VOID  Debugger::Workspace::onPaint()
{
  PAINTSTRUCT paint;
  Gdip::Graphics g(beginPaint(&paint));

  if (mDebugger.mPlayer)
  {
    Geom::Rect wContentRect = mDebugger.mPlayer.getRect();

    pointToClient(*(LPPOINT)&wContentRect.left);
    pointToClient(*(LPPOINT)&wContentRect.right);

    Gdip::Rect wContent = Gdip::Rect(
      wContentRect.left,
      wContentRect.top,
      wContentRect.getWidth(),
      wContentRect.getHeight());

    g.ExcludeClip(wContent);
    g.Clear(0xFF444444);
  }
  else
  {
    g.Clear(0xFFFFFFFF);
  }

  endPaint(&paint);
}

Debugger::Debugger() :
#pragma warning(disable : 4355)
  mWorkspace(*this)
#pragma warning(default : 4355)
{
  mPlayer = NULL;
}

VOID  Debugger::onCreate(Event::WndCreateEvent& iEvent)
{
  mLayout = getHandle();
  mLayout.style = LayoutDrag;

  mScript.create(*this, _T("Scintilla"), _T(""),
    WS_CHILD | ES_LEFT | ES_MULTILINE | WS_VSCROLL | ES_WANTRETURN);

  mScript.setID(DebuggerScript);

  mOutput.create(*this, _T("Scintilla"), _T(""),
    WS_CHILD | ES_LEFT | ES_MULTILINE | WS_VSCROLL | ES_WANTRETURN);

  mOutput.send(SCI_STYLESETBACK,  STYLE_DEFAULT, 0x444444);
  mOutput.send(SCI_STYLESETFORE,  STYLE_DEFAULT, 0xFFFFFF);
  mOutput.send(SCI_STYLESETSIZE,  STYLE_DEFAULT, 10);
  mOutput.send(SCI_STYLESETFONT,  STYLE_DEFAULT, (LPARAM)"Courier New");
  mOutput.send(SCI_STYLECLEARALL, NULL, NULL);
  mOutput.send(SCI_SETREADONLY,   TRUE, 0);

  mOutput.send(SCI_SETCARETLINEVISIBLE,   TRUE,      0);
  mOutput.send(SCI_SETCARETLINEBACK,      0x000000,  0);
  mOutput.send(SCI_SETCARETLINEBACKALPHA, 0x22,      0);
  mOutput.send(SCI_SETCARETSTYLE,         CARETSTYLE_BLOCK, 0);
  mOutput.send(SCI_SETCARETFORE,          0x222222,  0);

  mWorkspace.create(*this);

  API::InitializeEditor(mScript, Data::ScriptLua);
}

VOID  Debugger::onSize(Event::SizeEvent& iEvent)
{
  mLayout.doLayout();
}

VOID  Debugger::onEraseBackground(Event::EraseBackgroundEvent& iEvent)
{
  *iEvent.handled = TRUE;
}

VOID  Debugger::onPaint()
{
  PAINTSTRUCT paint;
  Gdip::Graphics g(beginPaint(&paint));

  g.Clear(0xFFFFFFFF);

  endPaint(&paint);
}

VOID  Debugger::onMouseDown(Event::MouseEvent& iEvent)
{
  mLayout.handleMouseDown(iEvent);
}

VOID  Debugger::onMouseUp(Event::MouseEvent& iEvent)
{
  mLayout.handleMouseUp(iEvent);
}

VOID  Debugger::onMouseMove(Event::MouseEvent& iEvent)
{
  mLayout.handleMouseMove(iEvent);
}

VOID  Debugger::onFocus(Event::FocusEvent& iEvent)
{
  mPlayer.activate();
  mPlayer.focus();
}

VOID  Debugger::setPlayer(HWND iHandle)
{
  mLayout.clear();

  if (mPlayer = iHandle)
  {
    LayoutElement* wControls = mLayout.addBottom(100);

    wControls->style = LayoutDrag;
    wControls->addRight(300, mOutput);
    wControls->addFill(mScript);

    mLayoutWorkspace = mLayout.addFill(mWorkspace);
    mLayoutWorkspace->margins.top = 4;
    mLayoutWorkspace->addElement(
      Geom::Size::get(
      Frame::get()->getProject().getGameWidth(),
      Frame::get()->getProject().getGameHeight()),
      mPlayer);

    mLayout.doLayout();
  }
  else
  {
    mLayoutWorkspace = NULL;
  }
}
